package com.google.code.ojar.sendtemplatemail.app;

import java.io.IOException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.code.ojar.sendtemplatemail.app.dto.Mail;
import com.google.code.ojar.sendtemplatemail.app.dto.NotSendMail;
import com.google.code.ojar.sendtemplatemail.app.exception.NotSendedMailException;
import com.google.code.ojar.sendtemplatemail.app.exception.SendMailException;
import com.google.code.ojar.sendtemplatemail.app.library.SendMailLibrary;
import com.google.code.ojar.sendtemplatemail.app.resendhandler.ResendFactory;
import com.google.code.ojar.sendtemplatemail.app.resendhandler.ResendHandler;
import com.google.code.ojar.sendtemplatemail.app.resendhandler.imp.XmlHandler;
import com.google.code.ojar.sendtemplatemail.app.utils.SendMailUtils;
import com.google.code.ojar.sendtemplatemail.report.SendManuallyReporter;

/**
 * Class that handle the resend of not sended mails
 * 
 * @author ottoabreu
 * 
 */
public class ReSendMail {
	// logger
	private static final Logger logger = LoggerFactory
			.getLogger(ReSendMail.class);

	/**
	 * Method incharge of resend the mails in xml format
	 * @throws IOException
	 * @throws Exception 
	 */
	public static void resendMail() throws IOException,Exception {
		logger.info("Starting resend...");
		ResendFactory factory = ResendFactory.getInstance();
		try {
			ResendHandler handler = factory.gethandler();
			List<NotSendMail> notSended;
			Integer policy = ReSendMail.retryPolicyReader();

			notSended = handler.read();
			logger.debug("notSended" + notSended);
			if (notSended != null && !notSended.isEmpty()) {
				logger.debug("tiene xml" + notSended.size());
				for (NotSendMail resend : notSended) {
					// verifico que pose politica de reintentos y que sea menor
					// o igual a lo que posee
					if (policy == null
							|| (policy != null && resend.getRetryCount() <= policy
									.intValue())) {
						Mail mail = resend.getMailBean();
						try {
							SendMail.send(mail);
							logger.info("Resend successfull: "
									+ resend.getMailBean().getSubject()
									+ " to:" + resend.getMailBean().getToAdds());
							ResendHandler.delete(resend.getFileName());
						} catch (SendMailException e) {
							if (e.isConnectionError()) {

								int retryCount = resend.getRetryCount() + 1;
								resend.setRetryCount(retryCount);
								logger.info("retry cont:" + retryCount);
								try {
									handler.generate(resend);
								} catch (NotSendedMailException e1) {
									logger.error(
											"can't recreate xml not sended: "
													+ resend.getMailBean()
															.getSubject()
													+ " to:"
													+ resend.getMailBean()
															.getToAdds()
													+ " due an exception", e);
									SendManuallyReporter
											.generateMauallyNotSendMail(resend,
													e);
								}
							}
						} catch (Exception e) {
							logger.error("can't resend mail: "
									+ resend.getMailBean().getSubject()
									+ " to:" + resend.getMailBean().getToAdds()
									+ " due an exception", e);
							SendManuallyReporter.generateMauallyNotSendMail(
									resend, e);
						}
					} else {
						logger.info("xml retry policy expired:"
								+ resend.getFileName() + " retry:"
								+ resend.getRetryCount()
								+ " file will be deleted");
						XmlHandler.delete(resend.getFileName());
						SendManuallyReporter.generateMauallyNotSendMail(resend,
								null);
					}
				}
			} else {
				logger.info("nothing to resend ^_^ ");
			}
		} catch (IOException e) {
			logger.error("can't read not sended mail xml due an IO error", e);
			throw e;
		} catch (Exception e) {
			logger.error("can't read not sended mail xml due an error", e);
			throw e;
		}

	}

	/**
	 * method in charge of obtain the number of retry to resend a mail
	 * 
	 * @return {@link Integer}
	 */
	private static Integer retryPolicyReader() {
		Integer numberRetry = null;

		String stringPolicy = SendMailUtils.getPropertiesString(
				SendMailLibrary.PROPERTY_FILE_NAME,
				SendMailLibrary.PROPERTY_KEY_RETRY_POLICY);
		if (stringPolicy != null && !stringPolicy.equals("")) {
			try {
				numberRetry = new Integer(stringPolicy);
				logger.info("retry policy is: " + numberRetry);
			} catch (NumberFormatException e) {
				logger.error("retry policy has to be a number, defined: "
						+ stringPolicy + " by default will be unlimited");
			}
		} else {
			logger.info("retry policy is unlimited");
		}
		return numberRetry;
	}
}
